﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using JSIF_WCFServer.Misc.Extensions;
using SharpSvn;

namespace JSIF_WCFServer.VersionControl
{
    /// <summary>
    /// A versioning interface that uses a subversion repository
    /// </summary>
    public class SVNVersionControl : IVersionControl
    {
        private DirectoryInfo _repositoryFolder;
        private SvnRepositoryClient _repositoryClient = new SvnRepositoryClient();
        private DirectoryInfo _workingFoldersRoot;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="repositoryFolder">the folder that has the repository (or the folder to create it in)</param>
        /// <param name="workingFolders">the folder to do working copy operations in</param>
        public SVNVersionControl(DirectoryInfo repositoryFolder, DirectoryInfo workingFolders)
        {
            if (repositoryFolder == null || workingFolders == null)
            {
                throw new ArgumentNullException();
            }
            if (repositoryFolder.isParentOf(workingFolders) || workingFolders.isParentOf(repositoryFolder))
            {
                throw new ArithmeticException("RepositoryFolder can't be the parent of the working folders or vice versa");
            }
            if (!workingFolders.Exists)
            {
                workingFolders.Create();
            }

            if (!repositoryFolder.Exists)
            {
                repositoryFolder.Create();
            }
            if (!_repositoryClient.isRepository(repositoryFolder))
            {
                SvnCreateRepositoryArgs args = new SvnCreateRepositoryArgs();
                _repositoryClient.CreateRepository(repositoryFolder.FullName, args);
            }
            _repositoryFolder = repositoryFolder;
            _workingFoldersRoot = workingFolders;
        }

        /// <summary>
        /// Returns a writeable instance of the head revision
        /// </summary>
        /// <param name="root">the root folder</param>
        /// <returns>a writeable instance of the head revision</returns>
        public IWriteableVersionControlInstance GetRootAtHead(String root)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Returns a readonly instance of a past revision
        /// </summary>
        /// <param name="root">the root folder</param>
        /// <param name="version">the version number</param>
        /// <returns>A readonly instance of a past revision</returns>
        public IReadOnylVersionControlInstance GetRootAtVersion(String root, int version)
        {
            throw new NotImplementedException();
        }

            /// <summary>
        /// Tells the version control instance that it can now reclaim and reuse any resources which were being held by the specified instance
        /// </summary>
        /// <param name="versionControlInstance">The instance to return to the pool</param>
        public void ReturnInstance(IReadOnylVersionControlInstance versionControlInstance)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Returns the list of root folders in this version controller
        /// </summary>
        /// <returns>the list of root folders in this version controller</returns>

        public IEnumerable<string> GetRoots()
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// Creates a new root
        /// </summary>
        /// <remarks>
        /// Calling this on an existing root should return the root to the "new" state, as if there was no existing book prior to the call.  There can be no naming restrictions, if necessary the version control implementation must map specified root names to an internale naming scheme transparently
        /// </remarks>
        /// <param name="root">the root folder</param>
        /// <param name="comment">a comment to associate with this change</param>
        /// <returns>true if the operation was successfull</returns>

        public bool CreateRoot(string root, string comment)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// Renames an existing root to something else
        /// </summary>
        /// <remarks>
        /// This is equivalent to calling "CopyRoot rootSource rootDest" followed by "DeleteRoot routeSource"
        /// </remarks>
        /// <param name="rootSource">the source root</param>
        /// <param name="rootDest">the destination root</param>
        /// <param name="comment">a comment to associate with this change</param>
        /// <returns>true if the operation was successfull</returns>

        public bool RenameRoot(string rootSource, string rootDest, string comment)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// Copies one root to another
        /// </summary>
        /// <remarks>
        /// If the destination root already existed, it would be replaced completly by the source as if there was nothing there previously.
        /// </remarks>
        /// <param name="rootSource">the source root</param>
        /// <param name="rootDest">the destination root</param>
        /// <param name="comment">a comment to associate with this change</param>
        /// <returns>true if the operation was successfull</returns>

        public bool CopyRoot(string rootSource, string rootDest, string comment)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// Deletes the specified root
        /// </summary>
        /// <param name="root">the root to delete</param>
        /// <param name="comment">a comment to associate with this change</param>
        /// <returns>true if the operation was successfull</returns>

        public bool DeleteRoot(string root, string comment)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Returns the history for the specified folder with the most recent changes listed first
        /// </summary>
        /// <param name="root">the root folder</param>
        /// <returns>the history for the specified folder with the most recent changes listed first</returns>

        public IEnumerable<string> GetHistory(string root)
        {
            throw new NotImplementedException();
        }
    }

    public class SVNWorkingCopy : IWriteableVersionControlInstance
    {
        /// <summary>
        /// Updates the working copy to the latest revision
        /// </summary>
        /// <returns>true if the operation was successful</returns>
        public bool Update()
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Commits any changes to the working copy
        /// </summary>
        /// <param name="comment">A comment to associate with the changes</param>
        /// <returns>true if the operation was successful</returns>
        public bool Commit(String comment)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Returns the names of the files present in the folder at the specified version
        /// </summary>
        /// <param name="root">the root folder</param>
        /// <param name="version">the version to inspect</param>
        /// <returns>the names of the files present in the folder at the specified version</returns>

        public IEnumerable<string> GetFileNames()
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Returns the contents of the specified file
        /// </summary>
        /// <param name="root">the root folder</param>
        /// <param name="version">the version to fetch</param>
        /// <param name="filename">the nameof the file to fetch</param>
        /// <returns>the contents of the specified file</returns>

        public byte[] GetFile(string filename)
        {
            throw new NotImplementedException();
        }
     
        /// <summary>
        /// Puts a file into the root
        /// </summary>
        /// <remarks>
        /// There can be no filename restrictions. If necessary the version control must maintain a mapping between the specified names and any internal naming scheme transparently.
        /// </remarks>
        /// <param name="filename">the name of the file</param>
        /// <param name="contents">the contents of the file</param>
        /// <returns>true if the operation was successfull</returns>

        public bool PutFile(string filename, byte[] contents)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// Deletes the specified file
        /// </summary>
        /// <param name="filename">the name of the file</param>
        /// <returns>true if the operation was successfull</returns>

        public bool DeleteFile(string filename)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// Renames a file
        /// </summary>
        /// <remarks>
        /// If the destination file already existed it will be overwritten
        /// </remarks>
        /// <param name="root">the root folder</param>
        /// <param name="filenameSource">the original name of the file</param>
        /// <param name="filenameDest">the new name of the file</param>
        /// <param name="comment">a comment to associate with this change</param>
        /// <returns>true if the operation was successfull</returns>

        public bool RenameFile(string filenameSource, string filenameDest)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// Copies a file
        /// </summary>
        /// <remarks>
        /// If the destination file already existed it will be overwritten
        /// </remarks>
        /// <param name="filenameSource">the source file</param>
        /// <param name="filenameDest">the destination file</param>
        /// <returns>true if the operation was successfull</returns>
        public bool CopyFile(string filenameSource, string filenameDest)
        {
            throw new NotImplementedException();
        }
    }
}
